/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.ui;

import java.io.IOException;
import java.io.File;

import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import phoside.PhosideInit;
import phoside.PhosphoProteins;
import phoside.PhosphoProteinsImpl;

import phoside.io.fasta.PhosphoReaderFromFastaWithSitesInSequence;
import phoside.io.fasta.parser.DefaultHeaderRule;
import phoside.io.xml.PhosideXmlProteinsWriter;
import phoside.io.xml.PhosphoProteinFieldValueFormatter;

import phoside.ui.task.ProteinsReadTask;
import phoside.ui.task.ProteinsWriteTask;
import phoside.ui.task.TaskUtil;

import phoside.util.FileExtensionsFilter;
import phoside.util.FilePathParser;

/**
 *
 * @author gjj
 */
public class Fasta2XmlDialog extends javax.swing.JDialog {

    /** Creates new form Fasta2XmlDialog */
    public Fasta2XmlDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        javax.swing.JPanel fastaPanel = new javax.swing.JPanel();
        javax.swing.JPanel fastaFilePanel = new javax.swing.JPanel();
        fastaFileTextField = new javax.swing.JTextField();
        javax.swing.JButton fastaFileButton = new javax.swing.JButton();
        javax.swing.JPanel fastaOptionPanel = new javax.swing.JPanel();
        javax.swing.JLabel accLabel = new javax.swing.JLabel();
        accTextField = new javax.swing.JTextField();
        javax.swing.JLabel nameLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        javax.swing.JLabel descLabel = new javax.swing.JLabel();
        descTextField = new javax.swing.JTextField();
        javax.swing.JLabel speciesLabel = new javax.swing.JLabel();
        speciesTextField = new javax.swing.JTextField();
        javax.swing.JPanel xmlPanel = new javax.swing.JPanel();
        javax.swing.JPanel xmlFilePanel = new javax.swing.JPanel();
        xmlFileTextField = new javax.swing.JTextField();
        javax.swing.JButton xmlFileButton = new javax.swing.JButton();
        javax.swing.JPanel OKPanel = new javax.swing.JPanel();
        OKBtn = new javax.swing.JButton();
        javax.swing.JButton cancelBtn = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Fasta to PHOSIDE XML");
        getContentPane().setLayout(new java.awt.GridBagLayout());

        fastaPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("From Fasta File"));
        fastaPanel.setLayout(new java.awt.GridBagLayout());

        fastaFilePanel.setLayout(new java.awt.GridBagLayout());

        fastaFileTextField.setToolTipText("Please select a FASTA training file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaFilePanel.add(fastaFileTextField, gridBagConstraints);

        fastaFileButton.setText("Open");
        fastaFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fastaFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaFilePanel.add(fastaFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        fastaPanel.add(fastaFilePanel, gridBagConstraints);

        fastaOptionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Regular expression to parse FASTA header"));
        fastaOptionPanel.setLayout(new java.awt.GridBagLayout());

        accLabel.setText("Accession:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(accLabel, gridBagConstraints);

        accTextField.setText("(.+)");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(accTextField, gridBagConstraints);

        nameLabel.setText("Symbol:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(nameLabel, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(nameTextField, gridBagConstraints);

        descLabel.setText("Description:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(descLabel, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(descTextField, gridBagConstraints);

        speciesLabel.setText("Species:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(speciesLabel, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaOptionPanel.add(speciesTextField, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        fastaPanel.add(fastaOptionPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(fastaPanel, gridBagConstraints);

        xmlPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Save to XML File"));
        xmlPanel.setMinimumSize(new java.awt.Dimension(400, 63));
        xmlPanel.setPreferredSize(new java.awt.Dimension(500, 63));
        xmlPanel.setLayout(new java.awt.GridBagLayout());

        xmlFilePanel.setLayout(new java.awt.GridBagLayout());

        xmlFileTextField.setToolTipText("Please select a FASTA training file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        xmlFilePanel.add(xmlFileTextField, gridBagConstraints);

        xmlFileButton.setText("Open");
        xmlFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                xmlFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        xmlFilePanel.add(xmlFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        xmlPanel.add(xmlFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(xmlPanel, gridBagConstraints);

        OKBtn.setText("   OK   ");
        OKBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OKBtnActionPerformed(evt);
            }
        });
        OKPanel.add(OKBtn);

        cancelBtn.setText("Cancel");
        cancelBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelBtnActionPerformed(evt);
            }
        });
        OKPanel.add(cancelBtn);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(OKPanel, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void fastaFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastaFileButtonActionPerformed
        JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = "fasta";
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"Fasta file (.fasta)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Select a Fasta file...");
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            fastaFileTextField.setText(filePath);

            String fileName = FilePathParser.getName(filePath);
            xmlFileTextField.setText(PhosideInit.defaultPath+File.separator+fileName+".xml");
        }
}//GEN-LAST:event_fastaFileButtonActionPerformed

    private void xmlFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_xmlFileButtonActionPerformed
        JFileChooser fc;
        String defFile = xmlFileTextField.getText();
        if (defFile.length()>0) {
            fc = new JFileChooser(FilePathParser.getDir(defFile));
        } else {
            fc = new JFileChooser(PhosideInit.defaultPath);
        }

        String ext = "xml";
        fc.setSelectedFile(new File(defFile));
        ArrayList<String> exts = new ArrayList<String>(1);
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"XML file (.xml)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Save to...");
        int returnVal = fc.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            xmlFileTextField.setText(filePath);
        }
    }//GEN-LAST:event_xmlFileButtonActionPerformed

    private void OKBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OKBtnActionPerformed
        String dirPhospho = fastaFileTextField.getText();
        if (dirPhospho.length()==0) {
            JOptionPane.showMessageDialog(this, "Error: specify a file containing the protein sequences.");
            return;
        }

        String dirXml = xmlFileTextField.getText();
        if (dirXml.length()==0) {
            JOptionPane.showMessageDialog(this, "Error: specify the xml file to save.");
            return;
        }

        if (phoside.util.IOUtil.fileExist(dirXml)) {
            int ret = JOptionPane.showConfirmDialog(this, "Are you sure to replace the existing xml file?",
                    null, JOptionPane.YES_NO_OPTION);
            if (ret==JOptionPane.NO_OPTION) {
                return;
            }
        }

        String accRegEx = accTextField.getText();
        if (accRegEx.length()==0) {
            JOptionPane.showMessageDialog(this, "Error: specify at least the regular expression for accession.");
            return;
        }

        String nameRegEx = nameTextField.getText();
        String descRegEx = descTextField.getText();
        String speciesRegEx = speciesTextField.getText();

        //Reading phospho data
        DefaultHeaderRule headerRule = new DefaultHeaderRule(accRegEx,
                nameRegEx.length()!=0?nameRegEx:null,
                descRegEx.length()!=0?descRegEx:null,
                speciesRegEx.length()!=0?speciesRegEx:null);
        PhosphoProteins phosphoData = new PhosphoProteinsImpl();
        PhosphoReaderFromFastaWithSitesInSequence phosphoReader;
        try {
           phosphoReader = new PhosphoReaderFromFastaWithSitesInSequence(dirPhospho,
                        phosphoData,headerRule);
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "Failed to read the fasta file");
            return;
        }

        ProteinsReadTask phosphoReadTask = new ProteinsReadTask(phosphoReader);
        TaskUtil.execute(phosphoReadTask);
        if (!phosphoReadTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to read the fasta file");
            return;
        }

        //Write to xml file
        PhosideXmlProteinsWriter writer = new PhosideXmlProteinsWriter(dirXml,
                new PhosphoProteinFieldValueFormatter());
        ProteinsWriteTask xmlWriteTask = new ProteinsWriteTask(phosphoData, writer);
        TaskUtil.execute(xmlWriteTask);
        if (!phosphoReadTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to write the xml file");
            return;
        }

        JOptionPane.showMessageDialog(this, "Successfully converted from FASTA to XML.");
        
        this.setVisible(false);
        this.dispose();
}//GEN-LAST:event_OKBtnActionPerformed

    private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelBtnActionPerformed
        setVisible(false);
        dispose();
}//GEN-LAST:event_cancelBtnActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton OKBtn;
    private javax.swing.JTextField accTextField;
    private javax.swing.JTextField descTextField;
    private javax.swing.JTextField fastaFileTextField;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JTextField speciesTextField;
    private javax.swing.JTextField xmlFileTextField;
    // End of variables declaration//GEN-END:variables

}
